home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dvips.new / dvips.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-15  |  17.7 KB  |  573 lines

  1. /*
  2.  *   This is the main routine.
  3.  */
  4. #ifndef DEFRES
  5. #define DEFRES (300)
  6. #endif
  7.  
  8. #include "structures.h" /* The copyright notice there is included too! */
  9. #ifdef VMS
  10. #define GLOBAL globaldef
  11. #include climsgdef
  12. #include ctype
  13. #include descrip
  14. #endif
  15. /*
  16.  *   First we define some globals.
  17.  */
  18. #ifdef VMS
  19.     static char ofnme[252],infnme[252],pap[40],thh[20];
  20. #endif
  21. fontdesctype *fonthead ;      /* list of all fonts mentioned so far */
  22. fontdesctype *curfnt ;        /* the currently selected font */
  23. sectiontype *sections ;       /* sections to process document in */
  24. Boolean manualfeed ;          /* manual feed? */
  25. Boolean compressed ;          /* compressed? */
  26. Boolean safetyenclose ;       /* enclose in save/restore for stupid spoolers? */
  27. Boolean removecomments ;      /* remove comments from included PS? */
  28. Boolean nosmallchars ;        /* disable small char optimization for X4045? */
  29. int collatedcopies = 1 ;      /* how many collated copies? */
  30. int sectioncopies = 1 ;       /* how many times to repeat each section? */
  31. shalfword linepos = 0 ;       /* where are we on the line being output? */
  32. integer maxpages ;            /* the maximum number of pages */
  33. Boolean notfirst, notlast ;   /* true if a first page was specified */
  34. Boolean sendcontrolD ;        /* should we send a control D at end? */
  35. integer firstpage ;           /* the number of the first page if specified */
  36. integer lastpage ;
  37. integer firstseq ;
  38. integer lastseq ;
  39. int numcopies ;               /* number of copies of each page to print */
  40. char *oname ;                 /* output file name */
  41. char *iname ;                 /* dvi file name */
  42. char *strings ;               /* strings for program */
  43. char *nextstring, *maxstring ; /* string pointers */
  44. FILE *dvifile, *bitfile ;     /* dvi and output files */
  45. quarterword *curpos ;         /* current position in virtual character packet */
  46. quarterword *curlim ;         /* final byte in virtual character packet */
  47. fontmaptype *ffont ;          /* first font in current frame */
  48. real conv ;                   /* conversion ratio, pixels per DVI unit */
  49. real vconv ;                  /* conversion ratio, pixels per DVI unit */
  50. real alpha ;                  /* conversion ratio, DVI unit per TFM unit */
  51. integer mag ;                 /* the magnification of this document */
  52. Boolean overridemag ;         /* substitute for mag value in DVI file? */
  53. int actualdpi = DEFRES ;      /* the actual resolution of the printer */
  54. int vactualdpi = DEFRES ;      /* the actual resolution of the printer */
  55. int maxdrift ;                /* max pixels away from true rounded position */
  56. int vmaxdrift ;                /* max pixels away from true rounded position */
  57. char *paperfmt ;              /* paper format */
  58. int landscape = 0 ;           /* landscape mode */
  59. integer fontmem ;             /* memory remaining in printer */
  60. integer pagecount ;           /* page counter for the sections */
  61. integer pagenum ;             /* the page number we currently look at */
  62. long bytesleft ;              /* number of bytes left in raster */
  63. quarterword *raster ;         /* area for raster manipulations */
  64. integer hh, vv ;              /* horizontal and vertical pixel positions */
  65. char *tfmpath = TFMPATH ;     /* pointer to directories for tfm files */
  66. char *pkpath = PKPATH ;       /* pointer to directories for pk files */
  67. char *vfpath = VFPATH ;       /* pointer to directories for vf files */
  68. char *figpath = FIGPATH ;     /* pointer to directories for figure files */
  69. char *headerpath = HEADERPATH ; /* pointer to directories for header files */
  70. char *configpath = CONFIGPATH;  /* where to find config files */
  71. #ifdef SEARCH_SUBDIRECTORIES
  72. char *fontsubdirpath = FONTSUBDIRPATH ;
  73. #endif
  74. #ifdef FONTLIB
  75. char *flipath = FLIPATH ;     /* pointer to directories for fli files */
  76. char *fliname = FLINAME ;     /* pointer to names of fli files */
  77. #endif
  78. integer swmem ;               /* font memory in the PostScript printer */
  79. int quiet ;                   /* should we only print errors to stderr? */
  80. int filter ;                  /* act as filter default output to stdout,
  81.                                                default input to stdin? */
  82. int prettycolumn ;            /* the column we are at when running pretty */
  83. int totalpages = 0 ;          /* total number of pages */
  84. Boolean reverse ;             /* are we going reverse? */
  85. Boolean usesPSfonts ;         /* do we use local PostScript fonts? */
  86. Boolean usesspecial ;         /* do we use \special? */
  87. Boolean headers_off ;         /* do we send headers or not? */
  88. char *headerfile ;            /* default header file */
  89. char *warningmsg ;            /* a message to write, if set in config file */
  90. Boolean multiplesects ;       /* more than one section? */
  91. Boolean disablecomments ;     /* should we suppress any EPSF comments? */
  92. char *printer ;               /* what printer to send this to? */
  93. char *mfmode ;                /* default MF mode */
  94. frametype frames[MAXFRAME] ;  /* stack for virtual fonts */
  95. fontdesctype *baseFonts[256] ; /* base fonts for dvi file */
  96. integer pagecost;               /* memory used on the page being prescanned */
  97. int delchar;                    /* characters to delete from prescanned page */
  98. integer fsizetol;               /* max dvi units error for psfile font sizes */
  99. Boolean includesfonts;          /* are fonts used in included psfiles? */
  100. fontdesctype *fonthd[MAXFONTHD];/* list headers for included fonts of 1 name */
  101. int nextfonthd;                 /* next unused fonthd[] index */
  102. char xdig[256];                 /* table for reading hexadecimal digits */
  103. char banner[] = BANNER ;        /* our startup message */
  104. Boolean noenv ;                 /* ignore PRINTER envir variable? */
  105. extern int dontmakefont ;
  106. #ifdef DEBUG
  107. integer debug_flag = 0;
  108. #endif /* DEBUG */
  109. /*
  110.  *   This routine calls the following externals:
  111.  */
  112. extern void outbangspecials() ;
  113. extern void prescanpages() ;
  114. extern void initprinter() ;
  115. extern void cleanprinter() ;
  116. extern void dosection() ;
  117. extern void getdefaults() ;
  118. extern void cmdout() ;
  119. extern void numout() ;
  120. extern int add_header() ;
  121. extern char *strcpy() ;
  122. extern void checkenv() ;
  123. extern void getpsinfo() ;
  124. #ifdef FONTLIB
  125. extern void fliload() ;
  126. #endif
  127. /*
  128.  *   This error routine prints an error message; if the first
  129.  *   character is !, it aborts the job.
  130.  */
  131. static char *progname ;
  132. void
  133. error(s)
  134.     char *s ;
  135. {
  136.    extern void exit() ;
  137.  
  138.    (void)fprintf(stderr, "%s: %s\n", progname, s) ;
  139.    if (*s=='!') {
  140.       if (bitfile != NULL) {
  141.          cleanprinter() ;
  142.       }
  143.       exit(1) ; /* fatal */
  144.    }
  145. }
  146.  
  147. /*
  148.  *   Initialize sets up all the globals and data structures.
  149.  */
  150. void
  151. initialize()
  152. {
  153.    extern char *malloc() ;
  154.    int i;
  155.    char *s;
  156.  
  157.    nextfonthd = 0;
  158.    for (i=0; i<256; i++)
  159.       xdig[i] = 0;
  160.    i = 0;
  161.    for (s="0123456789ABCDEF"; *s!=0; s++)
  162.       xdig[*s] = i++;
  163.    i = 10;
  164.    for (s="abcdef"; *s!=0; s++)
  165.       xdig[*s] = i++;
  166.    strings = malloc(STRINGSIZE) ;
  167.    if (strings == 0)
  168.       error("! no memory for strings") ;
  169.    maxpages = 100000 ;
  170.    numcopies = 1 ;
  171.    nextstring = strings ;
  172.    iname = strings ;
  173.    *nextstring++ = 0 ;
  174.    maxstring = strings + STRINGSIZE - 200 ;
  175.    bitfile = NULL ;
  176.    bytesleft = 0 ;
  177.    swmem = SWMEM ;
  178.    oname = OUTPATH ;
  179.    sendcontrolD = 0 ;
  180.    multiplesects = 0 ;
  181.    disablecomments = 0 ;
  182.    maxdrift = -1 ;
  183.    vmaxdrift = -1 ;
  184. }
  185. /*
  186.  *   This routine copies a string into the string `pool', safely.
  187.  */
  188. char *
  189. newstring(s)
  190.    char *s ;
  191. {
  192.    int l ;
  193.  
  194.    if (s == NULL)
  195.       return(NULL) ;
  196.    l = strlen(s) ;
  197.    if (nextstring + l >= maxstring)
  198.       error("! out of string space") ;
  199.    (void)strcpy(nextstring, s) ;
  200.    s = nextstring ;
  201.    nextstring += l + 1 ;
  202.    return(s) ;
  203. }
  204. /*
  205.  *   Finally, our main routine.
  206.  */
  207. #ifdef VMS
  208. main()
  209. #else
  210. void main(argc, argv)
  211.     int argc ;
  212.     char *argv[] ;
  213. #endif
  214. {
  215.    extern void exit() ;
  216.    int i, lastext = -1 ;
  217.    register sectiontype *sects ;
  218.  
  219. #ifdef VMS
  220.    progname = &thh[0] ;
  221.    strcpy(progname,"DVIPS%ERROR");
  222. #else
  223.    progname = argv[0] ;
  224. /* we sneak a look at the first arg in case it's debugging */
  225. #ifdef DEBUG
  226.    if (argc > 1 && strncmp(argv[1], "-d", 2)==0) {
  227.       if (sscanf(argv[1]+2, "%d", &debug_flag)==0)
  228.          debug_flag = 0 ;
  229.    }
  230. #endif
  231. #endif
  232.    initialize() ;
  233.    checkenv(0) ;
  234.    getdefaults(CONFIGFILE) ;
  235.    getdefaults((char *)0) ;
  236. /*
  237.  *   This next whole big section of code is straightforward; we just scan
  238.  *   the options.  An argument can either immediately follow its option letter
  239.  *   or be separated by spaces.  Any argument not preceded by '-' and an
  240.  *   option letter is considered a file name; the program complains if more
  241.  *   than one file name is given, and uses stdin if none is given.
  242.  */
  243. #ifdef VMS
  244. vmscli();
  245. #else
  246.    for (i=1; i<argc; i++) {
  247.       if (*argv[i]=='-') {
  248.          char *p=argv[i]+2 ;
  249.          char c=argv[i][1] ;
  250.          switch (c) {
  251. case 'c' :
  252.             if (*p == 0 && argv[i+1])
  253.                p = argv[++i] ;
  254.             if (sscanf(p, "%d", &numcopies)==0)
  255.                error("! Bad number of copies option (-c).") ;
  256.             break ;
  257. case 'd' :
  258. #ifdef DEBUG
  259.         if (*p == 0 && argv[i+1])
  260.            p = argv[++i];
  261.         if (sscanf(p, "%d", &debug_flag)==0)
  262.            error("! Bad debug option (-d).");
  263.         break;
  264. #else
  265.             error("not compiled in debug mode") ;
  266.             break ;
  267. #endif /* DEBUG */
  268. case 'e' :
  269.             if (*p == 0 && argv[i+1])
  270.                p = argv[++i] ;
  271.             if (sscanf(p, "%d", &maxdrift)==0 || maxdrift<0)
  272.                error("! Bad maxdrift option (-e).") ;
  273.         vmaxdrift = maxdrift;
  274.             break ;
  275. case 'f' :
  276.             filter = (*p != '0') ;
  277.             if (filter)
  278.                oname = "" ;
  279.             noenv = 1 ;
  280.             break ;
  281. case 'h' : case 'H' :
  282.             if (*p == 0 && argv[i+1])
  283.                p = argv[++i] ;
  284.             if (strcmp(p, "-") == 0)
  285.                headers_off = 1 ;
  286.             else
  287.                (void)add_header(p) ;
  288.             break ;
  289. case 'm' :
  290.             manualfeed = (*p != '0') ;
  291.             break ;
  292. case 'n' :
  293.             if (*p == 0 && argv[i+1])
  294.                p = argv[++i] ;
  295. #ifdef SHORTINT
  296.             if (sscanf(p, "%ld", &maxpages)==0)
  297. #else    /* ~SHORTINT */
  298.             if (sscanf(p, "%d", &maxpages)==0)
  299. #endif    /* ~SHORTINT */
  300.                error("! Bad number of pages option (-n).") ;
  301.             break ;
  302. case 'o' : case 'O' :
  303.             if (*p == 0 && argv[i+1] && *argv[i+1]!='-')
  304.                p = argv[++i] ;
  305.             oname = p ;
  306.             noenv = 1 ;
  307.             break ;
  308. case 'p' :
  309.             if (*p == 0 && argv[i+1])
  310.                p = argv[++i] ;
  311. #ifdef SHORTINT
  312.             switch(sscanf(p, "%d.%d", &firstpage, &firstseq)) {
  313. #else    /* ~SHORTINT */
  314.             switch(sscanf(p, "%ld.%ld", &firstpage, &firstseq)) {
  315. #endif    /* ~SHORTINT */
  316. case 1:        firstseq = 0 ;
  317. case 2:        break ;
  318. default:
  319.                error("! Bad first page option (-p).") ;
  320.             }
  321.             notfirst = 1 ;
  322.             break ;
  323. case 'l':
  324.             if (*p == 0 && argv[i+1])
  325.                p = argv[++i] ;
  326. #ifdef SHORTINT
  327.             switch(sscanf(p, "%d.%d", &lastpage, &lastseq)) {
  328. #else    /* ~SHORTINT */
  329.             switch(sscanf(p, "%ld.%ld", &lastpage, &lastseq)) {
  330. #endif    /* ~SHORTINT */
  331. case 1:        lastseq = 0 ;
  332. case 2:        break ;
  333. default:
  334.                error("! Bad last page option (-p).") ;
  335.             }
  336.             notlast = 1 ;
  337.             break ;
  338. case 'q' : case 'Q' :
  339.             quiet = (*p != '0') ;
  340.             break ;
  341. case 'r' :
  342.             reverse = (*p != '0') ;
  343.             break ;
  344. case 't' :
  345.             if (*p == 0 && argv[i+1])
  346.                p = argv[++i] ;
  347.             if (strcmp(p, "landscape") == 0)
  348.                landscape = 1;
  349.             else
  350.                paperfmt = p ;
  351.             break ;
  352. case 'x' :
  353.             if (*p == 0 && argv[i+1])
  354.                p = argv[++i] ;
  355.             if (sscanf(p, "%d", &mag)==0 || mag < 10 ||
  356.                        mag > 100000)
  357.                error("! Bad magnification parameter (-x).") ;
  358.             overridemag = 1 ;
  359.             break ;
  360. case 'C' :
  361.             if (*p == 0 && argv[i+1])
  362.                p = argv[++i] ;
  363.             if (sscanf(p, "%d", &collatedcopies)==0)
  364.                error("! Bad number of collated copies option (-C).") ;
  365.             break ;
  366. case 'D' :
  367.             if (*p == 0 && argv[i+1])
  368.                p = argv[++i] ;
  369.             if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  370.                        actualdpi > 10000)
  371.                error("! Bad dpi parameter (-D).") ;
  372.         vactualdpi = actualdpi;
  373.             break ;
  374. case 'K' :
  375.             removecomments = (*p != '0') ;
  376.             break ;
  377. case 'U' :
  378.             nosmallchars = (*p != '0') ;
  379.             break ;
  380. case 'X' :
  381.             if (*p == 0 && argv[i+1])
  382.                p = argv[++i] ;
  383.             if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  384.                        actualdpi > 10000)
  385.                error("! Bad dpi parameter (-D).") ;
  386.             break ;
  387. case 'Y' :
  388.             if (*p == 0 && argv[i+1])
  389.                p = argv[++i] ;
  390.             if (sscanf(p, "%d", &vactualdpi)==0 || vactualdpi < 10 ||
  391.                        vactualdpi > 10000)
  392.                error("! Bad dpi parameter (-D).") ;
  393.         vactualdpi = vactualdpi;
  394.             break ;
  395. case 'F' :
  396.             sendcontrolD = (*p != '0') ;
  397.             break ;
  398. case 'M':
  399.             dontmakefont = 1 ;
  400.             break ;
  401. case 'N' :
  402.             disablecomments = (*p != '0') ;
  403.             break ;
  404. case 'P' :
  405.             if (*p == 0 && argv[i+1])
  406.                p = argv[++i] ;
  407.             printer = p ;
  408.             noenv = 1 ;
  409.             getdefaults("") ;
  410.             break ;
  411. case 'R' :
  412.             reverse = 0 ;
  413.             break ;
  414. case 's' :
  415.             safetyenclose = (*p != '0') ;
  416.             break ;
  417. case 'Z' :
  418.             compressed = (*p != '0') ;
  419.             break ;
  420. case '?' :
  421.             (void)fprintf(stderr, banner) ;
  422.             break ;
  423. default:
  424.             error("! Bad option, not one of cefhlmnopqrtxCDFKNPUXYZ?") ;
  425.          }
  426.       } else {
  427.          if (*iname == 0) {
  428.             register char *p ;
  429.  
  430.             lastext = 0 ;
  431.             iname = nextstring ;
  432.             p = argv[i] ;
  433.             while (*p) {
  434.                *nextstring = *p++ ;
  435.                if (*nextstring == '.')
  436.                   lastext = nextstring - iname ;
  437.                else if (*nextstring == '/' || *nextstring == ':')
  438.                   lastext = 0 ;
  439.                nextstring++ ;
  440.             }
  441.             if (lastext == 0) {
  442.                lastext = nextstring - iname ;
  443.                *nextstring++ = '.' ;
  444.                *nextstring++ = 'd' ;
  445.                *nextstring++ = 'v' ;
  446.                *nextstring++ = 'i' ;
  447.             }
  448.             *nextstring++ = 0 ;
  449.          } else
  450.             error("! Two input file names specified.") ;
  451.       }
  452.    }
  453.    if (noenv == 0) {
  454.       register char *p ;
  455.       extern char *getenv() ;
  456.       if (p = getenv("PRINTER")) {
  457.          strcpy(nextstring, "config.") ;
  458.          strcat(nextstring, p) ;
  459.          getdefaults(nextstring) ;
  460.       }
  461.    }
  462. #endif
  463.    checkenv(1) ;
  464.    getpsinfo() ;
  465.    if (!quiet)
  466.       (void)fprintf(stderr, banner) ;
  467.    if (oname[0] == '-' && oname[1] == 0)
  468.       oname[0] = 0 ;
  469.    if (*oname == 0 && ! filter) {
  470.       oname = nextstring ;
  471.       for (i=0; i<=lastext; i++)
  472.          *nextstring++ = iname[i] ;
  473.       *nextstring++ = 'p' ;
  474.       *nextstring++ = 's' ;
  475.       *nextstring++ = 0 ;
  476.    }
  477. #ifdef DEBUG
  478.    if (dd(D_PATHS)) {
  479. #ifdef SHORTINT
  480.     (void)fprintf(stderr,"input file %s output file %s swmem %ld\n",
  481. #else /* ~SHORTINT */
  482.        (void)fprintf(stderr,"input file %s output file %s swmem %d\n",
  483. #endif /* ~SHORTINT */
  484.            iname, oname, swmem) ;
  485.    (void)fprintf(stderr,"tfm path %s\npk path %s\n", tfmpath, pkpath) ;
  486.    (void)fprintf(stderr,"fig path %s\nvf path %s\n", figpath, vfpath) ;
  487.    (void)fprintf(stderr,"config path %s\nheader path %s\n", 
  488.                   configpath, headerpath) ;
  489. #ifdef FONTLIB
  490.    (void)fprintf(stderr,"fli path %s\nfli names %s\n", flipath, fliname) ;
  491. #endif
  492.    } /* dd(D_PATHS) */
  493. #endif /* DEBUG */
  494. /*
  495.  *   Now we try to open the dvi file.
  496.  */
  497.    if (warningmsg)
  498.       error(warningmsg) ;
  499.    headerfile = (compressed? CHEADERFILE : HEADERFILE) ;
  500.    (void)add_header(headerfile) ;
  501.    if (*iname != 0)
  502.       dvifile = fopen(iname, READBIN) ;
  503.    else if (filter)
  504.       dvifile = stdin;
  505.    else
  506.       error("! No input filename supplied.") ;
  507.    if (dvifile==NULL)
  508.       error("! DVI file can't be opened.") ;
  509. #ifdef FONTLIB
  510.    fliload();    /* read the font libaries */
  511. #endif
  512. /*
  513.  *   Now we do our main work.
  514.  */
  515.    if (maxdrift < 0) {
  516.       if (actualdpi <= 599)
  517.          maxdrift = actualdpi / 100 ;
  518.       else if (actualdpi < 1199)
  519.          maxdrift = actualdpi / 200 + 3 ;
  520.       else
  521.          maxdrift = actualdpi / 400 + 6 ;
  522.    }
  523.    if (vmaxdrift < 0) {
  524.       if (vactualdpi <= 599)
  525.          vmaxdrift = vactualdpi / 100 ;
  526.       else if (vactualdpi < 1199)
  527.          vmaxdrift = vactualdpi / 200 + 3 ;
  528.       else
  529.          vmaxdrift = vactualdpi / 400 + 6 ;
  530.    }
  531.    prescanpages() ;
  532.    if (includesfonts)
  533.       (void)add_header(IFONTHEADER) ;
  534.    if (usesPSfonts)
  535.       (void)add_header(PSFONTHEADER) ;
  536.    if (usesspecial)
  537.       (void)add_header(SPECIALHEADER) ;
  538.    sects = sections ;
  539.    if (sects == NULL || sects->next == NULL) {
  540.       sectioncopies = collatedcopies ;
  541.       collatedcopies = 1 ;
  542.    } else {
  543.       totalpages *= collatedcopies ;
  544.       multiplesects = 1 ;
  545.    }
  546.    initprinter() ;
  547.    outbangspecials() ;
  548.    for (i=0; i<collatedcopies; i++) {
  549.       sects = sections ;
  550.       while (sects != NULL) {
  551.          if (! quiet) {
  552.             if (prettycolumn > 77) {
  553.                fprintf(stderr, "\n") ;
  554.                prettycolumn = 0 ;
  555.             }
  556.             (void)fprintf(stderr, ". ") ;
  557.             prettycolumn += 2 ;
  558.          }
  559.          (void)fflush(stderr) ;
  560.          dosection(sects, sectioncopies) ;
  561.          sects = sects->next ;
  562.       }
  563.    }
  564.    cleanprinter() ;
  565.    if (! quiet)
  566.       (void)fprintf(stderr, "\n") ;
  567.    exit(0) ;
  568.    /*NOTREACHED*/
  569. }
  570. #ifdef VMS
  571. #include "vms/vmscli.c"
  572. #endif
  573.